/** 仅仅是计算 g,b 距离的函数 */
const getDistance = (arr: RGB, arr1: RGB) => {
    // 不需要计算 r 值了，r 值是排序过的
    return (arr[1] - arr1[1]) ** 2 + (arr[2] - arr1[2]) ** 2;
};

export type ColorDetail = { name: string; rgb: RGB };
type RGB = [number, number, number] | number[];
/** 找到相近的颜色,
 * @params colors 是 r 值从小到大的数组
 *  */
export const findSimilarColor = (
    colors: ColorDetail[],
    rgb: RGB,
    RTolerate = 45,
    DistanceTolerate = 1000
) => {
    const collection: (ColorDetail & { distance: number })[] = [];
    const min = rgb[0] - RTolerate;
    const max = rgb[0] + RTolerate;
    colors.every((i) => {
        if (i.rgb[0] < max) {
            if (i.rgb[0] > min) {
                const d = getDistance(i.rgb, rgb);
                if (d <= DistanceTolerate) {
                    const result = {
                        ...i,
                        distance: d,
                    };
                    collection.push(result);
                }
            }

            return true;
        } else {
            //! 当遇到超越时结束,后面的值都是不合适的了
            return false;
        }
    });
    return collection;
};
/** 输入一个颜色数组，将会替换这些颜色为相似颜色的数组
 *
 * @params colors 是 r 值从小到大的数组
 */
export const replaceColors = (
    colors: ColorDetail[],
    RGBs: RGB[],
    RTolerate = 45,
    DistanceTolerate = 1000,
    inputSort = true
) => {
    const rgbs = RGBs.map((i) => i.map((ii) => ii)) as RGB[];
    inputSort && rgbs.sort((a, b) => a[0] - b[0]);

    const result = rgbs.map(() => [] as (ColorDetail & { distance: number })[]);
    const running = rgbs.map(
        () => [] as (ColorDetail & { distance: number })[]
    );
    colors.every((color) => {
        rgbs.forEach((rgb, index) => {
            const min = rgb[0] - RTolerate;
            const max = rgb[0] + RTolerate;
            if (color.rgb[0] < max) {
                if (color.rgb[0] > min) {
                    const d = getDistance(color.rgb, rgb);
                    if (d <= DistanceTolerate) {
                        const result = {
                            ...color,
                            distance: d,
                        };
                        running[index].push(result);
                    }
                }
            } else {
                //! 当遇到超越时结束,后面的值都是不合适的了
                result[index] = running[index];
                delete running[index];
            }
        });
        // ! 这里的意思是当 result 数组未充满时，继续
        return running.length !== result.length;
    });
    return running.map((i) => i.sort((a, b) => a.distance - b.distance));
};
